package com.dy.design_pattern_study.chain_of_responsibility_pattern.dome3;

import com.dy.design_pattern_study.chain_of_responsibility_pattern.dome3.impl.CommonManager;
import com.dy.design_pattern_study.chain_of_responsibility_pattern.dome3.impl.GeneralManager;
import com.dy.design_pattern_study.chain_of_responsibility_pattern.dome3.impl.Majordomo;

/**
 * @CreateBy zhangdingyi
 * @Date 2023-04-22
 * @Content 职责链模式（Chain of Responsibility）：
 * 使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。
 * 将这个对象连成一条链，并沿着这条链传递该请求，直到有一个对象处理它为止
 * <p>
 * 简单的说：
 * 就是把一个长长的if-else结构进行优化，可以任意的设置if-else的分支与顺序
 * 极大的简化复杂的if-else语句
 * 解耦、多层判断的if-else结构优化
 */
public class client {
    /*
        职责链模式的优点
        1.当客户提交一个请求时，请求是沿链传递直至有一个 Manager 对象负责处理它

        2.接收者和发送者都没有对方的明确信息，且链中的对象自己也并不知道链的结构。
        结果是职责链可简化对象的相互连接，它们仅需保持一个指向其后继者的引用，而不需保持它所有的候选接受者的引用
            简单的说，就是链结构由人主观的进行设置，可以任意的修改顺序。
            代码中，链中的对象并不知道具体链的结构，仅有一个后继者的引用

        2.1.随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性

        缺点
        1.一个请求极有可能到了链的末端都得不到处理，或者因为没有正确配置而得不到处理
     */

    /*
        职责链模式与状态模式的相同与区别
        相同：
        1.状态模式和职责链模式都是优化和处理复杂if-else结构

        不同：
        1.状态模式更偏向与改变状态，就是 对于某个状态的改变
        例子：12点吃饭，17点吃饭，到固定的时间，会由工作状态改变成吃饭状态

        2.职责链模式更偏向与处理信息，就是 给一个类，然后根据不同的信息会由不同的链对象进行处理
        如同本实例：请假信息、提薪信息，后面由不同的领导进行处理

        3.状态模式的状态是固定化的，灵活性较低，具体的状态类知道下一个节点

        4.职责链模式的请求处理是非常灵活的，可指定不同的处理顺序，具体的类并不知道下一个节点
     */

    public static void main(String[] args) {
        //三个管理者
        Manager personA = new CommonManager("经理");
        Manager personB = new Majordomo("总监");
        Manager personC = new GeneralManager("总经理");
        //设置等级
        personA.setSuperior(personB);
        personB.setSuperior(personC);

        Request request = new Request();
        request.setRequestType("加薪");
        request.setRequestContent("请求加薪");
        request.setNumber(1000);

        //加薪请求
        //具体的请求都由经理发起，最终处理的结果是谁进行处理，这里并不知道
        personA.resultApplications(request);

        Request request1 = new Request();
        request1.setRequestType("请假");
        request1.setRequestContent("请假3天");
        request1.setNumber(3);

        //请假请求
        personA.resultApplications(request1);
    }
}
